home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / netlog-1.02 / extract / extract.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-17  |  6.8 KB  |  308 lines

  1. /*
  2.      extract - A network log processor
  3.      Copyright (C) 1993 Douglas Lee Schales, David K. Hess, David R. Safford
  4.  
  5.      Please see the file `COPYING' for the complete copyright notice.
  6.  
  7. extract.c - 03/20/93
  8.  
  9. */
  10. #include <stdio.h>
  11. #include <sys/types.h>
  12. #include <sys/time.h>
  13. #include <netdb.h>
  14. #include <errno.h>
  15. #include <malloc.h>
  16. #include <unistd.h>
  17. #include <netinet/in.h>
  18.  
  19.  
  20. #include "extract.h"
  21. #include "chario.h"
  22. #include "parser.h"
  23. #include "interp.h"
  24. #include "stdunix.h"
  25.  
  26. extern char *inet_ntoa(struct in_addr);
  27. extern int getopt(int, char **, char *);
  28. extern char *optarg;
  29. extern int optind;
  30.  
  31. extern struct parsetree *parse(void);
  32. extern void extract(int, struct parsetree *);
  33. extern char *getportname(unsigned short);
  34. extern void flushbuf(void);
  35. extern void writebin(struct tcpsynout *);
  36. extern void writeascii(struct tcpsynout *);
  37. extern void writebuf(struct tcpsynout *);
  38. extern void setlogmode(int);
  39. extern void setlogfile(FILE *);
  40. extern char *gettimestr(struct timeval);
  41. static void helpscreen(char *);
  42.  
  43. #define LOGBINARY 0
  44. #define LOGASCII 1
  45.  
  46. int resolve = 1;
  47. #define TCPDATA 0
  48. #define UDPDATA 1
  49. int udptcpflag = TCPDATA;
  50.  
  51. int
  52. main(int argc, char **argv)
  53. {
  54.      struct parsetree *parsetree;
  55.      int logmode = LOGASCII;
  56.      FILE *outfile = stdout;
  57.      FILE *dumpfile = stdin;
  58.      int file = 0, expr = 0, errflag = 0;
  59.      int status;
  60.      char *membufname;
  61.      int c;
  62.  
  63.      while((c=getopt(argc, argv, "d:e:f:E:F:o:utabnh")) != -1){
  64.       switch(c){
  65.       case 'a':
  66.            logmode = LOGASCII;
  67.            break;
  68.       case 'b':
  69.            logmode = LOGBINARY;
  70.            break;
  71.       case 'n':
  72.            resolve = 0;
  73.            break;
  74.       case 't':
  75.            udptcpflag = TCPDATA;
  76.            break;
  77.       case 'u':
  78.            udptcpflag = UDPDATA;
  79.            break;
  80.       case 'f':
  81.            if((status = addfile(optarg)) != NOERR){
  82.             errflag++;
  83.             if(status == FILEERR){
  84.              perror(optarg);
  85.              exit(1);
  86.             }
  87.             else {
  88.              fprintf(stderr, "%s: unexpected error\n", optarg);
  89.              exit(1);
  90.             }
  91.            }
  92.            file++;
  93.            break;
  94.       case 'F':
  95.            if((status = includefile(optarg)) != NOERR){
  96.             errflag++;
  97.             if(status == FILEERR){
  98.              perror(optarg);
  99.              exit(1);
  100.             }
  101.             else {
  102.              fprintf(stderr, "%s: unexpected error\n", optarg);
  103.              exit(1);
  104.             }
  105.            }
  106.            file++;
  107.            break;
  108.       case 'e':
  109.            membufname = (char *)malloc(20);
  110.            sprintf(membufname, "argv[%d]", optind-1);
  111.            if((status = addmembuf(optarg, membufname)) != NOERR){
  112.             fprintf(stderr, "-e: unexpected error\n");
  113.             errflag++;
  114.            }
  115.            expr++;
  116.            break;
  117.       case 'E':
  118.            membufname = (char *)malloc(20);
  119.            sprintf(membufname, "argv[%d]", optind-1);
  120.            if((status = includemembuf(optarg, membufname)) != NOERR){
  121.             fprintf(stderr, "-E: unexpected error\n");
  122.             errflag++;
  123.            }
  124.            expr++;
  125.            break;
  126.       case 'd':
  127.            if(!(dumpfile = fopen(optarg, "r"))){
  128.             perror(optarg);
  129.             errflag++;
  130.            }
  131.            break;
  132.       case 'o':
  133.            if(!errflag && !(outfile = fopen(optarg, "w"))){
  134.             perror(optarg);
  135.             errflag++;
  136.            }
  137.            break;
  138.       case 'h':
  139.            helpscreen(argv[0]);
  140.            exit(0);
  141.            break;
  142.       default:
  143.            errflag++;
  144.            break;
  145.       }
  146.      }
  147.      if(errflag)
  148.       exit(1);
  149.  
  150.      if(!file && !expr)
  151.       addmembuf("{print}", "");
  152.  
  153.      setlogfile(outfile);
  154.      setlogmode(logmode);
  155.      if((parsetree = parse()))
  156.       extract(fileno(dumpfile), parsetree);
  157.      else
  158.       exit(1);
  159.      return 0;
  160. }
  161.  
  162. void
  163. helpscreen(char *name)
  164. {
  165.      fprintf(stdout,"\
  166. %s: usage: %s [options]\n\
  167.     options: -a        ASCII output (the default)\n\
  168.          -b        Binary output
  169.          -n        Use IP addresses for ASCII output\n\
  170.          -h        Print this help screen\n\
  171.          -e script    Specify script inline\n\
  172.          -E script    Specify script inline\n\
  173.          -f file    Specify script filename\n\
  174.          -F file    Specify script filename\n\
  175.          -d dumpfile    Specify dump file to process (def: stdin)\n\
  176.          -o outfile    Specify output file (def: stdout)\n\
  177. \n\
  178. %s processes a binary dump file created by 'tcpsynlogger',\n\
  179. selecting records to output.  The syntax of the script file is similar\n\
  180. to awk(1).  The script can be specified on the command line or can be\n\
  181. stored in a file.  All scripts specified by '-e', '-E', '-f', '-F' are\n\
  182. in effect, processed as a single file.  Scripts specified by '-e' and\n\
  183. '-f' are appended, whereas scripts specified by '-E' and '-F' are pre-\n\
  184. pended.  The use of '-E' or '-F' along with a '#!%s -f' script\n\
  185. executable allows insertion of additional script lines from the command\n\
  186. line.\n",
  187.          name, name, name, name);
  188. }
  189.  
  190. int
  191. nread(int fd, char *buf, int numbytes)
  192. {
  193.      int count = numbytes;
  194.      int n;
  195.  
  196.      while(count){
  197.       if((n = read(fd, buf, count)) > 0){
  198.            buf += n;
  199.            count -= n;
  200.       }
  201.       else
  202.            break;
  203.      }
  204.      return numbytes-count;
  205. }
  206.  
  207. void
  208. extract(int fd, struct parsetree *pt)
  209. {
  210.      struct tcpsynout buf[1000];
  211.      int i, n;
  212.  
  213.      while((n=nread(fd, (char *)&buf, sizeof(buf))) > 0){
  214.       for(i=0;i<(n/sizeof(struct tcpsynout));i++)
  215.            interp(&buf[i], pt);
  216.      }
  217.      flushbuf();
  218. }
  219.  
  220. int outlogmode = LOGBINARY;
  221. FILE *logfile = stdout;
  222.  
  223. void
  224. setlogfile(FILE *f)
  225. {
  226.      logfile = f;
  227. }
  228.  
  229. void
  230. setlogmode(int logmode)
  231. {
  232.      outlogmode = logmode;
  233. }
  234.  
  235. #define OUTBUFSIZE 1000
  236. struct tcpsynout outbuffer[OUTBUFSIZE];
  237. static int outptr = 0;
  238.  
  239. void
  240. writebuf(struct tcpsynout *outbuf)
  241. {
  242.      switch(outlogmode){
  243.      case LOGBINARY:
  244.       writebin(outbuf);
  245.       break;
  246.      case LOGASCII:
  247.       writeascii(outbuf);
  248.       break;
  249.      default:
  250.       fprintf(stderr, "Internal error... unknown output mode.\n");
  251.       exit(1);
  252.       break;
  253.      }
  254. }
  255.  
  256. void
  257. writebin(struct tcpsynout *outbuf)
  258. {
  259.      if(outptr == OUTBUFSIZE)
  260.       flushbuf();
  261.      memcpy(&outbuffer[outptr++], outbuf, sizeof(struct tcpsynout));
  262. }
  263.  
  264. void
  265. flushbuf(void)
  266. {
  267.      if(outptr)
  268.       write(fileno(logfile), (char *)outbuffer,
  269.         sizeof(struct tcpsynout)*outptr);
  270.      outptr = 0;
  271. }
  272.  
  273. void
  274. writeascii(struct tcpsynout *outbuf)
  275. {
  276.      struct in_addr haddr;
  277.      extern char *cgethostbyaddr(struct in_addr);
  278.  
  279.      fputs(gettimestr(outbuf->tp), logfile);
  280.      fprintf(logfile, " %8X ", outbuf->tcpseq);
  281.      memcpy(&haddr.s_addr, &outbuf->ipsrcaddr, 4);
  282.      fprintf(logfile, "%-21s", resolve ? cgethostbyaddr(haddr) : inet_ntoa(haddr));
  283.      fputc(' ', logfile);
  284.      fputs(getportname(outbuf->tcpsrcport), logfile);
  285.      fputs(" -> ", logfile);
  286.      memcpy(&haddr.s_addr, &outbuf->ipdstaddr, 4);
  287.      fprintf(logfile, "%-21s", resolve ? cgethostbyaddr(haddr) : inet_ntoa(haddr));
  288.      fputc(' ', logfile);
  289.      fputs(getportname(outbuf->tcpdstport), logfile);;
  290.      fputc('\n', logfile);
  291.      fflush(logfile);
  292. }
  293.  
  294. char *
  295. getportname(unsigned short p)
  296. {
  297.      struct servent *se;
  298.      static char result[80];
  299.  
  300.      if(resolve && (se = getservbyport((unsigned int)ntohs(p), 
  301.                 udptcpflag == TCPDATA ? "tcp" : "udp")))
  302.       strcpy(result, se->s_name);
  303.      else
  304.       sprintf(result, "%u", (unsigned int)ntohs(p));
  305.      
  306.      return result;
  307. }
  308.